Как минимум можно переносить данные с карты.Но таким образом ты заменишь то,что у тебя в карте.Другим способом по чуть чуть переносишь и ставишь всё как надо (требования всякие).Таким образом тебе как минимум не нужно будет делать описания и хар-ки.Ну или можешь сам их редактировать.В общем,такие дела.
Создаёшь в редакторе ИИ порядок действий, сохраняешь, импортируешь и запускаешь используя триггеры ( действия ИИ) для конкретного игрока (например: синий). Могу если нужно скинуть карту пример.
DracoL1ch, Не понял как я поменяю количество еды приносяший? DracoL1ch, или абилка такой есть? DracoL1ch, или ты имел виду создать типо так но на основе юнита (Сам писал)
set amount = R2I(amount) - R2I(this[u])
if amount < 0 then
set amount = -amount
set rawcode = rawcode + this.count
endif
set abilityId = this.count - 1
set abilityLevel = 4
set currentAbility = rawcode + abilityId
loop
exitwhen amount == 0
if amount >= powersOf2[abilityId * 3 + (abilityLevel - 2)] then
call UnitAddAbility(u, currentAbility)
call SetUnitAbilityLevel(u, currentAbility, abilityLevel)
call UnitRemoveAbility(u, currentAbility)
set amount = amount - powersOf2[abilityId * 3 + (abilityLevel - 2)]
else
set abilityLevel = abilityLevel - 1
if abilityLevel <= 1 then
set abilityId = abilityId - 1
set abilityLevel = 4
set currentAbility = rawcode + abilityId
endif
endif
endloop
Сделал если кому нужно контроль максимальной еды
// RUS: Создаем 8 юнит еду (Каждый шаг увиличивает 2ух-кратный)
//! runtextmacro UnitStart()
//! i CreateUnit("hfoo", "zxF", "ufma", "8", "FOOD", "BTNMonsterLure.blp")
//! runtextmacro UnitEnd()
//! textmacro UnitStart
/* RUS: Тут можно убрать если не стоит (MemoryHack)
//! externalblock extension=lua ObjectMerger $FILENAME$
//! i function CreateUnit(base, prefix, field, count, name, icon)
//! i k = 0
//! i j = 0
//! i for i = 0, (count - 1) do
//! i j = j + 1
//! i createobject(base, prefix .. string.sub(chars, k + 1, k + 1))
//! i makechange(current, "unam", "Unit - " .. name)
//! i makechange(current, "utip", "")
//! i makechange(current, "utub", "")
//! i makechange(current, "unsf", "(+" .. tostring(2^i) .. ")")
//! i makechange(current, "uico", "ReplaceableTextures\\CommandButtons\\" .. icon)
//! i makechange(current, field, 2^i)
//! i k = k + 1
//! i end
//! i end
//! i setobjecttype("units")
//! i chars = "abcdefghijklmnopqrstuvwxyz"
*/
//! endtextmacro
//! textmacro UnitEnd
/* RUS: Тут можно убрать если не стоит (MemoryHack)
//! endexternalblock
*/
//! endtextmacro
globals
constant integer xe_MAX_PLAYERS = 7
// RUS: Контроль еды
constant integer xe_COUNT_FOOD = 8
constant integer xe_RAWCODE_FOOD = 'zxFa'
endglobals
struct Food
private static group array groups[xe_MAX_PLAYERS]
private static integer array powers[xe_COUNT_FOOD]
private static method onInit takes nothing returns nothing
local integer i = 1
set thistype.powers[0] = 1
loop
exitwhen i > xe_COUNT_FOOD
set thistype.powers[i] = thistype.powers[i - 1] * 2
set i = i + 1
endloop
set i = 0
loop
exitwhen i == xe_MAX_PLAYERS
set thistype.groups[i] = CreateGroup()
set i = i + 1
endloop
endmethod
public static method operator []= takes player p, integer i returns nothing
local integer count = xe_COUNT_FOOD - 1
local group g = thistype.groups[GetPlayerId(p)]
local unit u = FirstOfGroup(g)
loop
exitwhen u == null
call RemoveUnit(u)
call GroupRemoveUnit(g, u)
set u = FirstOfGroup(g)
endloop
loop
exitwhen i == 0
if i >= thistype.powers[count] then
call GroupAddUnit(g, CreateUnit(p, xe_RAWCODE_FOOD + count, 0., 0., 0.))
set i = i - thistype.powers[count]
else
set count = count - 1
endif
endloop
set u = null
set g = null
endmethod
endstruct
в 1.26 так делал xgm.guru/p/wc3/163817
Ща mix убраны и архитектура wc переделана, но идея таже - внедриться в процесс варкрафта и найти оффсеты функций.
Насколько я знаю в мемхаке функции достаточно понятным образом называются. Но тем не менее, вот список того что вам может понадобиться. Мне кажется этого хватит для описываемых вами целей.
GetUnitBaseDamage
SetUnitBaseDamage
AddUnitBaseDamage
GetUnitBonusDamage
SetUnitBonusDamage
AddUnitBonusDamage
GetUnitTotalDamage
Я сам не проверял, но они должны выполнять указанную функцию.
А по поводу сохранения - вам понадобится правильная версия pjass, её можно найти в этой статье: xgm.guru/p/wc3/memory-hack, да и вообще в ней все написано про то как запустить мемхак.
И в целом, с мемхаком не нужно слишком сложно думать - нужно просто его поставить, найти нужную функцию и использовать. Благо функции как я уже говорил названы понятным образом.
На сайте, вот тут, есть хорошая статья об этом. Там не совсем то, что вам нужно, но на базе данного примера вы сможете создать всё самостоятельно.
+
И, между прочим, старый форум ещё никто не отменял.
AllChosen, ты пока что не понимаешь, что делаешь.
ты должен вместо цикла с вэйтом использовать "периодичный" таймер и сдвигать координаты, но пока что советуют посмотреть примеры xgm.guru/p/wc3/spellmaker-stomp-spell-creation
есть таймер одноразовый и периодичный, это все один и то же таймер, просто запускает разные режимы. через TimerStart. Вы таймер уже создали так смотрю, теперь нужно ловить запуски таймеров
Наименее ресурсозатратным для игрового процесса будет кастовать саму волну через отдельного дамми, который создаётся специально и только для волны силы. Сама волна наносит 1 ед урона. И потом определив, тип юнит-источника урона - наносим нужный урон от лица героя-хозяина юнита "волна силы".
В варианте "чекать группы каждые 0.0х сек" будет засоряться память и скорее всего будут подлагивания, в варианте со спец-дамиками засорится РО, выбирай из двух зол.
keks_090, чтобы кастовал бот - нужно триггерно приказать ему это сделать. Например, если тот же топот, то действие: Боевая единица - Приказ без цели (Issue Order With No Target), и выбираешь приказ: Вождь минотавров (Орда) - Громовая поступь. Аналогично с другими типами целей и спеллов. Нужно только выбрать приказ способности, на основе которой была создана триггерная способность.
Сделана как триггерная темная стая (гуи). Но с таким же успехом можно переделать под волну силы, огненное дыхание, девятый вал, ледяное дыхание. Все эти абилки похожие только спецэффекты разные.
Есть триггерные действия на смену текстуры в точке, но там тоже есть предел на их количество.
Где-то здесь на хгме был генератор рандомного ландшафта на триггерах, и там случайно выпадает зимний/осенний ланд и т.д.
Когда загружаешь модель, нужно перезагрузить World editor. Если и так не отображаются, может, ты указал неправильный путь к файлам в импорте(смотри видео)
function PolarProjectionX takes real x, real dist, real angle returns real
return x + dist * Cos(angle * bj_DEGTORAD)
endfunction
function PolarProjectionY takes real y, real dist, real angle returns real
return y + dist * Sin(angle * bj_DEGTORAD)
endfunction
function Trig_Hit_Actions takes nothing returns nothing
local unit caster = GetTriggerUnit()
local real face = GetUnitFacing(caster)
local real x = PolarProjectionX(GetUnitX(caster), 100., face)
local real y = PolarProjectionY(GetUnitY(caster), 100., face)
local group targets = CreateGroup()
local unit target
call GroupEnumUnitsInRange(targets, x, y, 100., null)
set target = FindClosestToXY(targets, x, y)
if target != null then
call UnitDamageTargetBJ(caster, target, 100., ATTACK_TYPE_CHAOS, DAMAGE_TYPE_UNIVERSAL)
set target = null
endif
set caster = null
call DestroyGroup(targets)
set targets = null
endfunction
The Dude, это несерьезно. Все вопросы описаны в большом количестве статей здесь, на нашем сайте - xgm.guru/p/wc3/articles. То, что перечисляешь не верх мастерства WE, а базовые знания. Материалов предостаточно. Успехов в обучении.
ZeroCaty:
Окей. Я понял, у тебя всё по дефолту. Я имел в виду параметры, которые влияют на то, где, как и когда ИИ строит здание. Немного наврал, там не тип использования, там тип расположения.
вроде как кулдаун не запускается, если в момент применения способности юнита переместить триггером в какое-нибудь другое место (например, на несколько точек вправо)
Я решил это через отслеживание начала заклинания, после чего ставил юнита на паузу на 20 сек с проигрыванием анимации. т.е. способность не завершалась, но выгляедло это так, как будто она завершилась
void - это nothing то есть ничего не возвращает функция, а саму функции называют doTheThing, а unit u - аргументы функции, мануалы про cjass почитай (хотя я тоже соглашусь, что написано очень плохо в мануалах. Нужно попробовать немного самим пописать коды)
можно представить как (если хорошо понимаешь jass)
function doTheThing takes unit u returns nothing
... //что-то делаешь с юнитом u (берем аргумент функции - unit u)
endfunction
GetMyUnit - такой не существует, видимо Док имеет в виду подставить свою переменную
пример
например составил пример функции - определить уровень абилы юнита. Функция называется LV, u - юнит, id - целое число, равкод абилы. Возвращает целое число (уровень абилы).
function LV takes unit u, integer id returns integer
return GetUnitAbilityLevel(u, id)
endfunction
'A000' - равкод абилы
local integer lv = LV(GetTriggerUnit(), 'A000') //узнаем уровень героя
вы мне скинули абсолютно пустую карту с отключенным триггером. А где код? Она у меня норм без проблем запустилась.
вам для работы с lua лучше отказаться от гуи. Вы лишаетесь большого инструмента.
Пример Назарова смотрите с движением снарядов ссылка. там показывают. Ну он же есть. Берете пример prog с хуком, и вставляете триггеры
неправильное событие у вас стоит, тк координаты мыши не получить
это какой то простой код, видимо вы пытаетесь понять как запустить. два показательных примера покажу:
первый - вставляете код
do -- создаём область видимости, чтоб не конфликтовать с другим кодом
local InitGlobalsOrigin = InitGlobals -- хукаем функцию InitGlobals
function InitGlobals()
InitGlobalsOrigin()
-- в этом моменте прошла инициализация карты и можно смело работать
FogEnableOff()
FogMaskEnableOff()
--создаем триггеры
local MouseMove = CreateTrigger( )
TriggerRegisterPlayerMouseEventBJ( MouseMove, Player(0), bj_MOUSEEVENTTYPE_MOVE )
TriggerAddAction( MouseMove, function()
--CreateUnitByName(GetLocalPlayer(),'footman',BlzGetTriggerPlayerMouseX(),BlzGetTriggerPlayerMouseY())
print("координаты: "..BlzGetTriggerPlayerMouseX()..","..BlzGetTriggerPlayerMouseY())
CreateUnit(Player(0),FourCC('hfoo'),BlzGetTriggerPlayerMouseX(),BlzGetTriggerPlayerMouseY(),0)
end)
--end
end
end
второй - с использованием гуи
function onMouseClick()
--CreateUnitByName(GetLocalPlayer(),'footman',BlzGetTriggerPlayerMouseX(),BlzGetTriggerPlayerMouseY())
print("координаты: "..BlzGetTriggerPlayerMouseX()..","..BlzGetTriggerPlayerMouseY())
CreateUnit(Player(0),FourCC('hfoo'),BlzGetTriggerPlayerMouseX(),BlzGetTriggerPlayerMouseY(),0)
end
карта пример прилагается. дело не программе, а в кривых руках)
Стандартный ИИ никак, только если вы замените канал какими-то другим скиллом, который юзает ИИ в схожей ситуации ( если нужно чтобы ии юзал спелл в толпе то подойдет вызов волка или стомп в качестве пустышки). Ну или совсем радикальный вариант, писать свой ИИ.
Как верно всё импортировать
Открываешь свою карту, открываешь мою. Переходишь в редактор юнитов, выбираешь там Dummy, жмёшь Ctrl + C (копировать). Далее вверху "Окна" -> твоя карта. Как только она откроется, жми Ctrl + V (вставить). Появится окошко с выбором равкода, ничего не меняй, жми Ок.
Переходишь в мою карту с помощью меню "Окна". Как только она откроется, перейди в редактор способностей. Также, как ты делал выше, скопируй Bomb Attached, Explode, Put Bomb, War Stomp Dummy.
После этого перейди в свою карту, дай своему юниту, который будет кастовать твою способность, способности Explode и Put Bomb как геройские.
Теперь перейди в мою карту, скопируй все триггеры из категории Bomb, триггер BomberEntersMap копируй самым последним.
В триггере BomberEntersMap, 2 раза кликни по условию и замени выделенное поле на картинке на тип своего юнита. Больше ничего там не трогай!
Далее открываешь переменные в своей карте. Открываешь BomberAbilBombAttached, заменяешь начальное значение на скопированную из моей карты способность Bomb Attached. Аналогично поступаешь с переменными BomberAbilExplode, BomberAbilPutBomb и BomberDummyAbil.
Если всё верно сделаешь, должно работать.
Всё дополнительная информация в комментариях в триггерах.
Всё это будет работать только для 1 героя со способностью Put Bomb на карте.
Если что-то сломается или будут вопросы, то пиши в ЛС, а тут отметь этот комментарий как ответ на вопрос.
Это вообще никак не влияет. Ты ещё скажи, что set a = a + 1 не работает.
Дело может быть в том, что юнит за 10 секунд разлагается.
немного исправленный код
function Reborn takes nothing returns nothing
local timer t = GetExpiredTimer()
local integer s = GetHandleId(t)
local unit dead = LoadUnitHandle (udg_hash, s, 6)
call FlushChildHashtable(udg_hash, s)
call CreateUnit(GetOwningPlayer(dead), GetUnitTypeId(dead), GetUnitX(dead), GetUnitY(dead), GetUnitFacing(dead))
call DestroyTimer(t)
set dead = null
set t = null
endfunction
function Trig_Kill_Unit_Actions takes nothing returns nothing
local unit dead = GetTriggerUnit() //Присваиваем убитого юнита
local timer t = CreateTimer() //Создаём таймер
local integer s = GetHandleId(t) //Узнаём его ID
call SaveUnitHandle(udg_hash, s, 6, dead) //Сохраняем юнита
call TimerStart(t, 10, false, function Reborn) //Активируем одноразовый таймер на 10 секунд
set dead = null
set t = null
endfunction
код с учётом разложения
function Reborn takes nothing returns nothing
local timer t = GetExpiredTimer()
local integer s = GetHandleId(t)
local player p = LoadPlayerHandle(udg_hash, s, 0)
local integer id = LoadInteger(udg_hash, s, 0)
local real x = LoadReal(udg_hash, s, 0)
local real y = LoadReal(udg_hash, s, 1)
local real f = LoadReal(udg_hash, s, 2)
call CreateUnit(p, id, x, y, f)
call FlushChildHashtable(udg_hash, s)
call DestroyTimer(t)
set t = null
set p = null
endfunction
function Trig_Kill_Unit_Actions takes nothing returns nothing
local unit dead = GetTriggerUnit()
local timer t = CreateTimer()
local integer s = GetHandleId(t)
call SavePlayerHandle(udg_hash, s, 0, GetOwningPlayer(dead))
call SaveInteger(udg_hash, s, 0, GetUnitTypeId(dead))
call SaveReal(udg_hash, s, 0, GetUnitX(dead))
call SaveReal(udg_hash, s, 1, GetUnitY(dead))
call SaveReal(udg_hash, s, 2, GetUnitFacing(dead))
call TimerStart(t, 10, false, function Reborn)
set dead = null
set t = null
endfunction
и в коде куча утечек PhysCraft, да это вобще пример того как не надо кодить EnergyFrost, норм EnergyFrost, так же замени глобалки локалками
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(s.a),dammyBallCasterId,GetUnitX(F),GetUnitY(F),GetUnitFacing(F))
за такое положен расстрел EnergyFrost, проще написать новый чем этот править
Всё зависит от мелочей... если ты хочешь запаузить всех кто в данный момент находится на карте - это одно, если вообще ВСЕХ и ВСЁ - это другое...
Стомп застанит только тех, по кому попадёт... те кто появятся после - не будут застанены
Молотбурь застанит только тех, кого укажешь... кого не укажешь - не будут застанены
Пауза работать будет так же как молот, но так паузить баффы и прочее...
Можно собрать стан, который будет станить на 0.00 сек (вечно), а далее его снимать вручную... но тут надо учесть то что все станы должны будут это учитывать (или быть такими же - время таймерное).
. . .
По факту, когда я планировал перевести баффы на триггерную основу (тайминг), пришёл к выводу что мои баффы "обездвиживание" (сетка), "безмолвие" (сало), "обезоруживание" (дизарм - склад) и дополнительный бафф на "сковывание" (скорость поворота на 0), давали в сумме следующее:
нельзя двигаться и поворачиваться
нельзя кастовать
нельзя атаковать
В итоге это практически тот же стан... но с набором баффов в статусе (сетка и сало минимум)
создаешь объект, спрашиваешь, какой у него handle
если меньше 0x100000 - беспокоиться не о чем, он локальный и сам разрушится, если не помешаешь ссылками на него (да и то не факт, что это влияет для них). тем паче, что даже в нативке указывается, вечная или нет деформация
этот (terraindeform) - локальный, если что.
Какие-то объекты могут создавать зависимости, осовбожегние хендла не значит, что объект чисто удален. В целом это всё уже из области псевдопрограммирования - не стоит волновться о таких мелочах. Create & Destroy работают достаточно хорошо. И да, объекты это все agent
type agent extends handle all reference counted objects
Причина: причин было много, а я искал лишь одну
Самыми распространёнными оказались элементарные ошибки в коде, отсутствие параметров, параметры не того типа данных (привет динамическая типизация) или лишние параметры, из за чего происходили "рандомные рассинхроны при обрыве потока"
Огромное спасибо пользователю prog, что откликнулся и смог найти ошибки, а нашёл он их при помощи языкового сервера sumneko lua для VScode
orix, когда в каком. Было бы полезно будь это какая-то особая, уличная, прога. Но оказывается вопрос был о том как в блендере язык поменять... Это не та информация с поиском которой могут даже потенциально возникнуть проблемы. Коммент скрыл из-за ссылки на портал третьей стороны, не имеющей никакого отношения к программе о которой шла речь.
какое отношение этот пункт имеет к проблеме?
короче покопался в wtg файле
у тебя раньше использовался какой то странный файл гуишных функций
скорее всего он лежал либо в папке с вар3, либо в папке с джнгп и потом его удалили
одна из функций (возвращает булеан) вообще была представлена как набор пробелов
узнавать что это была за функция мне было лень поэтому я её заменил на false (использовалась в условии)
это было в триггере ctart, так что поправь там условие
так же заменил IssueImmediateOrderBJ на IssueImmediateOrder
вот открываемая в редакторе карта
Просто юзай инг редактор, я вообще удивляюсь, зачем всё это переводили - перевести нормально так и не смогли. Часть полей называется как-то адово, даже не близко к реальности
Проблема решилась написанием SquareRoot в формуле вычисления дистанции. Странно, что в другом скилле мною эта формула использовалась с этой же ошибкой (SquareRoot не писал, забывал, наверное, из-за неопытности), но при этом все работало нормально... Мистика какая-то. Но буду признателен за другие предложения по оптимизации кода)) ScopteRectuS:
Покажите лучше карту, пока руками не потрогаешь, сложно сказать где проблема.
И да, так как углы известны уже заранее, то можно сразу же посчитать их:
local real point_1_x = target_x + 300.00 * Cos(0.00*bj_DEGTORAD)
local real point_1_y = target_y + 300.00 * Sin(0.00*bj_DEGTORAD)
>>>>
local real point_1_x = target_x + 300.00 * 1.0
local real point_1_y = target_y + 300.00 * 0.0
>>>>
local real point_1_x = target_x + 300.00
local real point_1_y = target_y + 0.00
>>>>
local real point_1_x = target_x + 300.00
local real point_1_y = target_y
Благодарю, проблему нашел. Всегда так, когда в отчаянии на форум бегу - дак тут же проблему увидел, а до этого - хрен)
Я посмотрел, но возникла проблема. Я тупой и не могу написать также, но моменте добаления юнита в хеш таблицу. Я Save Handle of (Last created unit) as 0 of (а дальше я не нашёл, как добавть "Key(Constructed structure))" in Hash
и соответсвенно любое другое действие, где прописанно Key
Так не нужно ничего самому делать. Я прикрепил к тому сообщению карту. В ней я уже все сделал сам. Тебе осталось только скопировать триггеры оттуда в свою карту и заменить юнитов на тех, которые тебе нужны. Вот та карта:
Ответ выше - для стандартного редактора WE. Однако, рекомендуется использовать с Lua внешний редактор кода и внешний же сборщик карты. Это чревато маленьким неудобством в виде необходимости запускать карту на проверку только из внешней программы т.к. запуск из WE будет без значительной части кода в карте, но дает огромное преимущество в виде несравнимо более удобной работы с кодом.
К сожалению, пока слишком мало информации об этом на сайте.
Вариант NazarPunk, пока без сборки карты, код придется копировать в карту вручную.
Мой вариант, пока не рабочий т.к. перед релизом нужно исправить несколько багов, но включает в себя и работу с кодом и сборку карты, не нужно вручную копировать код в карту.
Даже здесь на сайте есть еще пара вариантов, но мне лень их искать
И немного саморекламы, как выглядели бы ответы на вопрос выше при использовании моего тулсета
Использовать макрос RAW('A0E5'), который превратит равкод в число при сборке карты.
Инжект в функцию main, с заменой оригинальной функции main на свою и вызовом оригинальной функции изнутри нашей.
Аналогично ответу на этот вопрос для чистого WE, но без объявления переменных в WE т.к. то уже не так удобно становится когда код во внешнем редакторе.
Теперь о точках входа и инжекте.
Луа позволяет делать такой финт ушами
do
local f = FunctionName -- записываем функцию в переменную
function FunctionName() -- заменяем оригинальную функцию своей
f() -- вызываем оригинальную функцию из переменной
-- здесь могла быть ваша реклама или ваш код
end
end
Это позволит нам сохранить оригинальную функцию в переменную, заменить оригинал своей функцией и вызвать оригинал из переменной. Применимо к любой функции, которая была объявлена раньше, не работает если функция объявлена после выполнения этого кода. Для создания точки входа отлично подходит InitGlobals, она всегда объявляется раньше кастомного кода в WE и вызывается из main.
У себя в коде я пользуюсь немного более сложным способом, этот код не будет работать в WE т.к. цепляет main, а не InitGlobals и не дает серьеных преимуществ перед описаным выше, привожу просто для расширения кругозора
local function InjectMain()
local alpha_main = main
return function()
local alpha_init = RunInitializationTriggers
RunInitializationTriggers = function() end
alpha_main()
InitLibraries() --моя функция, которая должна быть выполнена после всего, но до триггеров инициализации карты
alpha_init()
end
end
main = InjectMain()
ну не обнулили g
во-вторых, не привязали группу при ее создании к выбранному юниту. Короче, это уже ошибка.
if g == null then
set g = CreateGroup()
//надо в хэш на зэндл выбранного записать группу
set g = null //переменная - это просто ссылка
endif
при смерти овцы удаляем ее из группы
при смерти выбранного юнита удаляем группу
может стоит подумать сделать на всю игру одну группу овечек или вообще обойтись без группы. будет фиксировать заход/выход овцы. На каждого выбранного заводим счетчик. А каждой овце привязываем выбранного. Когда овца умирает, то зная к кому привязана, у выбранного понижаем счетчик.
В целом не нужно, я думаю, если ты все поля при создании структуры инициализируешь (я не уверен обнуляет ли их аллокатор)
Структура просто integer потому что в коде в итоге генерирутся параллельные массивы т.е. например
real array cord_x
real array cord_y
real array cord_z
unit array cord_u
Для каждого члена структуры. Поэтом сама cord это просто индекс в эти массивы. Когда ты делаешь cord.create() находится свободный индекс в этих "параллельных" массивах и помечается заполненным.
Это тот же принцип для второго пункта, мне казалось, что могут быть способы изящнее. Лучше по другим пунктам подскажите.
первый вопрос так и не понял, насчет третьего вопроса:
там весь прикол в ивентах, есть начало когда наводишь на цель, тогда даже анимация не проигрывается и мана не забирается.
Приводит в действие это уже когда ману сняло и проигралась анимация.
Где то был текст на всё это, но я не могу найти.
Ну а далее чекаешь уровень бафа у цели, если он больше 0 - значит хиляешь и удаляешь баф
Хотя возможно это я неправильно понял, можно просто отловить начало каста абилки и восстанавливать ману триггерно.
AgaraSatan, так и думал.
там нужно не тип "исследуемый юнит", там другая переменная "переключаемый юнит (англ. triggering unit)". Исследуемый юнит - работает при событии юнит изучает/исследует. у тебя условие просто не прокатывает. делай дебаги
К несчастью большинство ативок не стакается, сильный бафф подавляет более слабый (к примеру замедление), некоторые просто заменяют старый бафф новым (яды), поэтому триггерные баффы делаются на основе аур, идеально для негативных баффов подходит 'Aasl' - Аура замедления (торнадо), у ней нету иконки, поэтому ей можно просто добавить юниту, не морочась с запрещенными спелбуками.
Нужно подсовывать ауру для баффа и постоянную невидимость волков юниту, а триггерно проверять все параметры и удалять эту ауру и постоянную невидимость.
В качестве активки у кастера используй обычный канал.
Ты никак не заставишь одиноаковые заклинания стакнуться. Делай спеллы-пустышки, баффы вешай аурами, которые потом будешь удалять, эффекты заклинания делай триггерно. Иначе никак.
Единственное, что ещё, применимое именно к лечению - можно создавать несколько фонтанов жизни или юнитов с их способностью и регенить сильнее за счёт одной и той же способности.
нет нельзя, т.к баффы это внутриигровые триггеры, которые привязаны к конкретному юниту.
то что весит в статусе - это тупо визуалка, можно взять яд стрелы и указать в настройках бафы другой абилки и пожалуйста, вот вам бафф который ничего не делает.
» WarCraft 3 / Функция ForGroup
» WarCraft 3 / Редактирование иконок
» WarCraft 3 / Кампании
» WarCraft 3 / Функции МемХака
» WarCraft 3 / Добавление зеленого урона.
» WarCraft 3 / Способность прыжок
» WarCraft 3 / Вычисление урона героя
» WarCraft 3 / Триггерная волна силы
» WarCraft 3 / Эффект выстрела остаётся
» WarCraft 3 / Как можно заменить тайл?
» WarCraft 3 / Почему. Просто почему.
» WarCraft 3 / Вопрос по редактору карт
» WarCraft 3 / После применения способности? ИИ застывает.
» WarCraft 3 / Вопрос про UnitDamageTarget?
» WarCraft 3 / Ошибка в коде ИИ
» WarCraft 3 / Заставить ИИ применить способность
» WarCraft 3 / Хеш-таблица на ГУИ.
» WarCraft 3 / деформация земли
» WarCraft 3 / Следовать за юнитом триггерно?
» WarCraft 3 / Английский редактор
» WarCraft 3 / помощь со скиллом
» WarCraft 3 / Объясните код
» WarCraft 3 / Восстановление маны в колодцах
» WarCraft 3 / Алгоритм построения юнитов
» WarCraft 3 / Баффы и Дебаффы